package com.seeyon.apps.ssoAndDoc.utils;

import com.alibaba.fastjson.JSONObject;
import com.aspose.words.Document;
import com.aspose.words.SaveFormat;
import com.seeyon.apps.collaboration.po.ColSummary;
import com.seeyon.apps.form.manager.FormManager;
import com.seeyon.apps.govdoc.helper.GovdocContentHelper;
import com.seeyon.apps.ssoAndDoc.dao.DownLoadContentDao;
import com.seeyon.cap4.template.bean.ScreenCapture4FormParamBean;
import com.seeyon.cap4.template.service.CAPScreenCaptureService;
import com.seeyon.ctp.common.AppContext;
import com.seeyon.ctp.common.ModuleType;
import com.seeyon.ctp.common.content.comment.Comment;
import com.seeyon.ctp.common.content.comment.CommentManager;
import com.seeyon.ctp.common.filemanager.manager.AttachmentManager;
import com.seeyon.ctp.common.filemanager.manager.FileManager;
import com.seeyon.ctp.common.htmltopdf.manager.HtmlToPdfManager;
import com.seeyon.ctp.common.po.content.CtpContentAll;
import com.seeyon.ctp.common.po.filemanager.Attachment;
import com.seeyon.ctp.common.po.filemanager.V3XFile;
import com.seeyon.ctp.util.FileUtil;
import com.seeyon.v3x.edoc.domain.EdocSummary;
import com.seeyon.v3x.edoc.manager.EdocFormManager;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class WdToPdfUtil {
	private static final Log logger = LogFactory.getLog(WdToPdfUtil.class);
//	private static String oaUrl = "http://" + System.getProperty("docArchive.oaPort");
//
//	static AffairManager affairManager = (AffairManager) AppContext.getBean("affairManager");
//	static FormApi4Cap4 formApi4Cap4 = (FormApi4Cap4) AppContext.getBean("formApi4Cap4");
//	static HtmlToPdfManager htmltopdfManager = (HtmlToPdfManager) AppContext.getBean("htmltopdfManager");
//	static FileManager fileManager = (FileManager) AppContext.getBean("fileManager");
//	static EdocFormManager edocFormManager = (EdocFormManager) AppContext.getBean("edocFormManager");
protected static FileManager fileManager  = (FileManager) AppContext.getBean("fileManager");
protected static AttachmentManager attachmentManager  = (AttachmentManager) AppContext.getBean("attachmentManager");
protected static DownLoadContentDao downLoadContentDao = (DownLoadContentDao) AppContext.getBean("downLoadContentDao");

    public static void colFromToSummary(Map<String, Object> params, StringBuffer errorMessage) {
		// pdf存放路径
		String targetPath = params.get("targetPath").toString();
		String contentPath = String.valueOf(params.get("contentPath"));
		ColSummary colSummary = (ColSummary) params.get("summary");
		String contentHtmlPath = contentPath + File.separator + colSummary.getSubject() + ".html";
		File filePath = new File(contentPath);
		if (!filePath.exists()) {
			filePath.mkdir();
		}
		File htmlFile = new File(contentHtmlPath);
		if (!htmlFile.exists()) {
			try {
				htmlFile.createNewFile();
			} catch (IOException e) {
				logger.error("创建流程表单正文HTML文件异常", e);
			}
		}

		CAPScreenCaptureService capScreenCaptureService = (CAPScreenCaptureService) AppContext
				.getBean("capScreenCaptureService");
		ScreenCapture4FormParamBean screenCapture4FormParamBean = new ScreenCapture4FormParamBean();
		screenCapture4FormParamBean.setRightId(params.get("rightId").toString());
		screenCapture4FormParamBean.setModuleType(Integer.valueOf(params.get("moduleType").toString()));
		screenCapture4FormParamBean.setModuleId(Long.valueOf(params.get("moduleId").toString()));;
		String contentHtml = capScreenCaptureService.doFormDataContentScreenCapture(screenCapture4FormParamBean);
		String optionHtml = optionToHtml(Long.valueOf(params.get("moduleId").toString()),1);
		StringBuilder sb = new StringBuilder();
		PrintStream ps = null;
		//标题和日期Html
		Date date = new Date();
		SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
		String dateString = formatter.format(date);
		String subjectHtml = "";
		subjectHtml = subjectHtml+"<table style=\"margin:0 auto;border-collapse:collapse;\" border=0 width=\"700px\"><tr><td align=\"left\"><span size=\"2\">"+dateString+"</span></td></tr>";
		subjectHtml = subjectHtml+"<tr><th><font size=\"6\">"+params.get("subject")+"</font></th></tr>";
		subjectHtml = subjectHtml+"<tr><th><font size=\"2\">"+params.get("createname")+"&nbsp;&nbsp;"+params.get("createTime")+"</font></th></tr>";
		subjectHtml = subjectHtml+"<tr><td height=\"60px\"></td></tr></table>";
		try {
			ps = new PrintStream(new FileOutputStream(htmlFile));
			sb.append("<html><head><title>colTempHtml</title><meta charset=\"GBK\"></meta><meta content=\"text/html\" http-equiv=\"Content-Type\"></meta>");
			sb.append("<div align='center'>");
			sb.append(subjectHtml);
			sb.append(contentHtml);
			sb.append(optionHtml);
			sb.append("</div>");
			sb.append("</html>");
			ps.println(sb.toString());
		} catch (FileNotFoundException e) {
			logger.error("生成流程表单正文HTML文件异常", e);
		} finally {
			if (ps != null) {
				ps.close();
			}
		}

		/*File pdfFile = new File(targetPath);
		File pdfFolder = pdfFile.getParentFile();
		if (!pdfFolder.exists()) {
			pdfFolder.mkdirs();
		}*/

		HtmlToPdfManager htmlToPdfManager = (HtmlToPdfManager) AppContext.getBean("htmltopdfManager");
		htmlToPdfManager.singleHtmlToPdf(contentHtmlPath, targetPath, null);
	}

	public static String optionToHtml(Long moduleId,int moduleType) {
		String html = "";
		try {
			//Long moduleId = colSummary.getId();
			CommentManager commentManager = (CommentManager) AppContext.getBean("ctpCommentManager");
			ModuleType mType = ModuleType.getEnumByKey(moduleType);
			List<Comment> com = commentManager.getCommentAllByModuleId(mType, moduleId);

			List<Comment> fqrCom = new ArrayList<Comment>();
			List<Comment> clrCom = new ArrayList<Comment>();
			List<Comment> clrHfCom = new ArrayList<Comment>();
			for (Comment comment : com) {
				//发起人附言
				if(comment.getCtype()==-1){
					fqrCom.add(comment);
				}else if(comment.getCtype()==0){
					//处理人意见
					clrCom.add(comment);
				}else if(comment.getCtype()==1){
					//处理人意见区回复
					clrHfCom.add(comment);
				}
			}

			html = "<table style=\"margin:0 auto;border-collapse:collapse;\" border=0 width=\"700px\">";
			html = html + "<tr style=\"height:40px;\">";
			html = html + "<th colspan=\"5\" align=\"left\" bgcolor=\"#FFF7DA\">发起人附言</th>";
			html = html + "</tr>";
			for (Comment comment : fqrCom) {
				//发起人附言
				if(comment.getCtype()==-1){
					html = html + "<tr colspan=\"5\" style=\"height:35px;\"><td align=\"left\">"+comment.getContent()+"</td></tr>"+"<tr colspan=\"5\" style=\"height:35px;\"><td align=\"left\"><font color=\"#A3A3A3\">"+comment.getCreateDateStr()+"</font></td></tr>";
				}
			}
			html = html + "<tr><td height=\"20px\"></td></tr>";
			html = html + "<tr style=\"height:40px;\">";
			html = html + "<th colspan=\"5\" align=\"left\" bgcolor=\"#E1EAF1\">处理人意见区</th>";
			html = html + "</tr>";
			for (Comment comment : clrCom) {
				html = html + "<tr><td height=\"20px\"></td></tr>";
				//处理人意见区
				if(comment.getCtype()==0){
					html = html + "<tr style=\"height:35px;\" bgcolor=\"#F0F0F0\">";
					html = html + "<td style=\"width:90px;word-wrap:break-word;\"><font color=\"#4D97F3\">"+comment.getCreateName()+"</font></td>"+"<td style=\"width:90px;word-wrap:break-word;\">"+comment.getExtAtt1I18n()+"</td>"+
							"<td style=\"width:140px;word-wrap:break-word;\" colspan=\"3\"><font color=\"#A3A3A3\">"+comment.getCreateDateStr()+"</font></td></tr>";
					if(comment.getContent()!=""&&comment.getContent()!=null&&!"".equals(comment.getContent())){
						html = html +"<tr><td height=\"20px\"></td></tr>";
					}
					html = html +"<tr><td colspan=\"5\" style=\"WORD-WRAP: break-word\" width=\"20\">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;"+comment.getContent()+"</td></tr>";

					//此意见的回复
					/* Long commentId = comment.getId();
					 for(Comment comment2 : clrHfCom){
						 if(comment2.getPid()!=null&& comment2.getPid().longValue()==commentId.longValue()){
							 html = html +"<p><a>"+comment2.getCreateName()+"</a><span>&nbsp&nbsp&nbsp&nbsp</span><span>"+comment2.getCreateDateStr()+"<span></p>"+"<div>"+comment2.getContent()+"<div>";
						 }
					 }
					 html = html + "</li></ul></div>";*/
				}
			}
			html = html + "</table>";
		} catch (Exception e) {
			// TODO: handle exception
		}
		return html;
	}
	//pdf转换
	public static boolean createFormImageFile(String summaryId, String meetingId, String affairId, String category, String pdfPathFolder,Cookie[] cookies) {
		boolean toPdfState = false;
		try{
			String formUrl = "";
			HttpServletRequest request = AppContext.getRawRequest();// 获取服务器信息
			String scheme = request.getScheme();
			String serverName = request.getServerName();
			int serverPort = request.getServerPort();
			String serverIP = scheme + "://" + serverName + ":" + serverPort;
			Long userId = AppContext.getCurrentUser().getId();
			if ("meeting".equals(category)){//会议下载
				logger.info("----sht----会议转pdf开始: ");
				//拼接工具url
				Map params = request.getParameterMap();
				formUrl = serverIP + "/seeyon/wdToPdfLogin.do?method=showForm&moduleId=" + affairId + "&userId=" + userId + "&meetingId=" + meetingId;
				logger.info("----sht----会议转pdf的免登陆URL: "+formUrl);
				File file = new File(pdfPathFolder);
				if (!file.exists()) {
					file.createNewFile();
				}
				toPdfState = toPdfState(formUrl, pdfPathFolder, cookies);
			}else{//公文单下载
				logger.info("----sht----公文单转pdf开始: ");
				//拼接工具url
				EdocFormManager edocFormManager = (EdocFormManager) AppContext.getBean("edocFormManager");
				//boolean isSuccess = edocFormManager.writeForm2File2(Long.parseLong(summaryId), pdfPathFolder);
				formUrl = serverIP + "/seeyon/ssoAndDocControl.do?method=showForm&moduleId=" + summaryId + "&userId=" + userId + "&affairId=" + affairId + "&summaryId=" + summaryId;
				JSONObject jsonObject = new JSONObject();
				jsonObject.put("loginName", "oa1");
				jsonObject.put("time", System.currentTimeMillis());
				String jsonString = jsonObject.toString();
				String ticket;
				ticket = Base64Util.getBaseString(jsonString.getBytes(StandardCharsets.UTF_8));
				String ticket1 = URLEncoder.encode(ticket, StandardCharsets.UTF_8.toString());
				String toUrl = URLEncoder.encode("/seeyon/govdoc/govdoc.do?method=summary&affairId=7738309697272040509&openFrom=listDone","utf-8");
				formUrl = "http://localhost:8283/seeyon/login/sso?from=myjsxysso&ticket="+ticket1+"&tourl="+toUrl;
				logger.info("----sht----公文单转pdf的免登陆URL: "+formUrl);
				File file = new File(pdfPathFolder);
				if (!file.exists()) {
					file.createNewFile();
				}
				toPdfState = toPdfState(formUrl, pdfPathFolder, cookies);
			}
		} catch (Exception e) {
			logger.error("---sht---文单转PDF出现异常:", e);
		}
		return toPdfState;
	}

	//转换方法
	public static boolean toPdfState(String url, String pdfPathFolder, Cookie[] cookies){
		//使用wkhtmltopdf工具进行转换
		boolean flag = TransformationUtils.transUrlToPdf(url, pdfPathFolder,cookies);
		if(flag) {
			logger.info("----sht----调用转pdf软件转换成功,返回值为:"+flag);
		}else {
			logger.info("----sht----调用转pdf软件转换失败,返回值为:"+flag);
		}
		if (new File(pdfPathFolder).exists()) {
			return true;
		}
		return false;
	}

	public static void edocFromToSummary(Map<String, Object> params, StringBuffer errorMessage) {
		EdocSummary summay = (EdocSummary) params.get("summay");
		String attachTempPath = (String) params.get("attachTempPath");
		String tempPath = (String) params.get("tempPath");

		EdocFormManager edocFormManager = (EdocFormManager) AppContext.getBean("edocFormManager");

		//boolean isSuccess = edocFormManager.writeForm2File2(summay.getId(), tempPath);
		int maxRetries = 5; // 最大重试次数
		int attempt = 0; // 当前尝试次数
		boolean isSuccess = false; // 成功标志

		while (attempt < maxRetries) {
			isSuccess = edocFormManager.writeForm2File2(summay.getId(), tempPath);
			if (isSuccess) {
				break;
			}
			attempt++;
			System.out.println("尝试 " + attempt + " 失败，等待 1 秒后重试...");
			try {
				Thread.sleep(1000); // 等待 1 秒
			} catch (InterruptedException e) {
				Thread.currentThread().interrupt(); // 处理线程中断
				logger.info("写入html线程中断");
				break;
			}
		}
		if(!isSuccess){
			errorMessage.append("文单获取失败;");
			return ;
		}
		String  edocFormHtmlFilePath = tempPath+ File.separator + summay.getId() + File.separator + "form.html";
		//文单pdf存放路径
		String attachTempPaths = tempPath+ File.separator + summay.getId() + File.separator+summay.getSubject()+"-";
		HtmlToPdfManager htmlToPdfManager = (HtmlToPdfManager )AppContext.getBean("htmltopdfManager");
		String edocFromPdfName = htmlToPdfManager.singleHtmlToPdf(edocFormHtmlFilePath, attachTempPaths, null);
		//获取 文单.pdf
		String oldPath = attachTempPaths+edocFromPdfName;
		String newPath =attachTempPath+File.separator+summay.getSubject()+"-文单.pdf";
		try {
			TheBodyOfTheDownload.downWenSingleFile(oldPath,newPath);
		} catch (Exception e) {
			logger.error("获取文单pdf异常",e);
		}

		if(!"error".equals(edocFromPdfName)){
			logger.info("TWL--文单转pdf 文件路径：" + attachTempPath + edocFromPdfName);
		}else{
			errorMessage.append("文档转pdf错误");
		}
	}


	public static void  accessToTheBody(Map<String, Object> params, StringBuffer errorMessage){
		EdocSummary summay = (EdocSummary) params.get("summay");
		Long summaryId = summay.getId();
		String attachTempPath = (String) params.get("attachTempPath");
		logger.info("TWL-获取正文---start");
		CtpContentAll ctpContentAll = GovdocContentHelper.getBodyContentByModuleId(summay.getId());
		int contentType = ctpContentAll.getContentType();
		logger.info("下载正文的类型:"+contentType);
		String content = ctpContentAll.getContent();
		String suffix = getSuffixByContentType(contentType);
		if("".equals(suffix)){
			logger.info("TWL-'" + summay.getSubject() + "'的正文类型无法识别;contentType:" + contentType + ";summaryId" + summay.getId());
			errorMessage.append("'" + summay.getSubject() + "'的正文类型无法识别;");
			return;
		}
		try {
			if(contentType != 10){
				String fileSubject = summay.getSubject();
				CtpContentAll downLoadContentAll = ctpContentAll;
				if (downLoadContentAll==null){
                     return;
				}
				String fileExtensions = getFileExtensionsByContentType(contentType);
				String contentName = replaceBlank(fileSubject)+"-正文"+ fileExtensions;
				logger.info("正文文件名："+contentName);
				//正文ID
				Long contentId = Long.parseLong(content);
				File tempFile = fileManager.getSpicFile(contentId, true);
				String newPath =  attachTempPath +File.separator+ contentName;
				File newFile = new File(newPath);
				// 确保父目录存在
				File parentDir = newFile.getParentFile();
				if (parentDir != null && !parentDir.exists()) {
					parentDir.mkdirs(); // 创建所有必要的父目录
				}
				// 判断是否存在newFile
				if (!newFile.exists()) {
					newFile.createNewFile();
				}
				InputStream in = new FileInputStream(tempFile);
				OutputStream out = new FileOutputStream(newFile);
				byte[] buffer = new byte[1024];
				int len;
				// 循环取出流中的数据
				while ((len = in.read(buffer)) != -1) {
					out.write(buffer, 0, len);
				}
				if(out != null){
					out.close();
				}
				if(in != null){
					in.close();
				}
			}else{
				//html
				Map<String, Object> fileParams = new HashMap<>();
				fileParams.put("content", content);
				fileParams.put("subject", summay.getSubject());
				fileParams.put("attachTempPath", attachTempPath);
				fileParams.put("summay",summay);
				logger.info("TWL-html正文---start");
				TheBodyOfTheDownload.createHtml(fileParams);
				logger.info("TWL-html正文---end");
			}
		} catch (Exception e) {
			logger.error("TWL-获取正文错误 summaryId" + summay.getId(), e);
			errorMessage.append("'" + summay.getSubject() + "'获取正文错误;");
		}
		logger.info("TWL-获取正文---end");
	}

	private static String getSuffixByContentType (int contentType){
		String suffix = "";
		switch (contentType) {
			case 41:
				suffix = ".doc";
				break;
			case 42:
				suffix = ".xls";
				break;
			case 43:
				suffix = ".docx";
				break;
			case 44:
				suffix = ".xlsx";
				break;
			case 45:
				suffix = ".pdf";
				break;
			case 10:
				suffix = ".html";
				break;
			default:
				break;
		}
		return suffix;
	}

	public static void word2pdf(Map<String, Object> params) throws Exception {
		File oldFile = (File) params.get("oldFile");
		String subject = (String) params.get("subject");
		String attachTempPath = (String) params.get("attachTempPath");
		String targetfile = attachTempPath + subject + "--正文.pdf";

		Document doc = new Document(oldFile.getPath());
		doc.acceptAllRevisions();
		doc.save(targetfile, SaveFormat.PDF);
	}

	public static void accessToTheAttachment(Map<String, Object> params, StringBuffer errorMessage) throws Exception {
		EdocSummary summay = (EdocSummary) params.get("summay");
		String attachTempPath = (String) params.get("attachTempPath");
		List<Attachment> attachments = attachmentManager.getByReference(summay.getId());
		for (Attachment attachment : attachments) {
			if(attachment.getType()  != 2) {
				File attachmentFile = fileManager.getSpicFile(attachment.getFileUrl(), true);
				String pdfPath = attachTempPath +File.separator+ summay.getSubject() + "-" + "附件" + attachment.getFilename();
				File pdfFile = new File(pdfPath);
				// 确保父目录存在
				File parentDir = pdfFile.getParentFile();
				if (parentDir != null && !parentDir.exists()) {
					parentDir.mkdirs(); // 创建所有必要的父目录
				}
				// 判断是否存在newFile
				if (!pdfFile.exists()) {
					pdfFile.createNewFile();
				}
				FileUtil.copyFile(attachmentFile, pdfFile);
			}
		}
	}

	private static CtpContentAll getDownLoadContentAll(Long summaryId) throws Exception{
		List<CtpContentAll> tempContents = new ArrayList<CtpContentAll>(2);
		List<CtpContentAll> allContents = downLoadContentDao.getContentListByModuleId(summaryId);
		for (CtpContentAll ctpContentAll : allContents) {
			Integer contentType = ctpContentAll.getContentType();
			//排除文单的记录
			if(contentType != 20){
				tempContents.add(ctpContentAll);
			}
		}

		if(tempContents.size() == 1){
			//只有一个正文
			CtpContentAll ctpContentAll = tempContents.get(0);
			return ctpContentAll;
		}else{
			//多正文只获取版式文件 pdf 45  fxofd 53  ofd 46
			for (CtpContentAll ctpContentAll : tempContents) {
				if(ctpContentAll.getContentType() == 45 || ctpContentAll.getContentType() == 53 || ctpContentAll.getContentType() == 46){
					return ctpContentAll;
				}
			}
			//多正文且未找到版式文件则代表有错误
			return null;
		}
	}

	public static String getFileExtensionsByContentType(int contentType){
		String fileExtensions = "";
		if(contentType == 41 || contentType == 43 || contentType == 51){
			fileExtensions = ".doc";
		}else if(contentType == 42 || contentType == 44 || contentType == 52){
			fileExtensions = ".xls";
		}else if(contentType == 45){
			fileExtensions = ".pdf";
		}else if(contentType == 53 || contentType == 46){
			fileExtensions = ".ofd";
		}else{
			fileExtensions = "";
		}
		return fileExtensions;
	}

	public static String replaceBlank(String content) {
		String dest = "";
		if (content!=null) {
			Pattern p = Pattern.compile("\t|\r|\n");
			Matcher m = p.matcher(content);
			dest = m.replaceAll("");
		}
		return dest;
	}

	public static void deleteDirectory(Path path) throws IOException {
		// 递归删除文件夹中的所有内容
		if (Files.isDirectory(path)) {
			// 遍历文件夹中的所有文件和子文件夹
			Files.list(path).forEach(file -> {
				try {
					deleteDirectory(file);
				} catch (IOException e) {
					System.err.println("无法删除文件: " + e.getMessage());
				}
			});
		}
		// 删除空文件夹或文件
		Files.delete(path);
	}

	public static void zipDirectory(ZipOutputStream zipOut, String sourceDir, String baseDir) throws IOException {
		File dir = new File(sourceDir);
		File[] files = dir.listFiles();

		if (files != null) {
			for (File file : files) {
				if (file.isDirectory()) {
					// 递归处理子目录
					zipDirectory(zipOut, file.getAbsolutePath(), baseDir + file.getName() + "/");
				} else {
					// 添加文件到 ZIP
					try (FileInputStream fileIn = new FileInputStream(file)) {
						ZipEntry zipEntry = new ZipEntry(baseDir + file.getName());
						zipOut.putNextEntry(zipEntry);

						byte[] buffer = new byte[4096]; // 使用更大的缓冲区
						int length;
						while ((length = fileIn.read(buffer)) >= 0) {
							zipOut.write(buffer, 0, length);
						}
						zipOut.closeEntry();
					} catch (IOException e) {
						System.err.println("无法添加文件到 ZIP: " + file.getName() + ", 错误: " + e.getMessage());
					}
				}
			}
		}
	}

}
